﻿using Sgr.Domain.Uow.Database;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Sgr.Domain.Uow
{
    /// <summary>
    /// 子工作单元实现
    /// </summary>
    /// <remarks>
    /// 子工作单元是对父工作单元的一个轻量级包装，它：
    /// 1. 共享父工作单元的事务和资源
    /// 2. 转发大部分操作到父工作单元
    /// 3. 提供对父工作单元操作的追踪
    /// </remarks>
    internal class ChildUnitOfWork : IUnitOfWork
    {
        private readonly IUnitOfWork _parent;

        /// <summary>
        /// 初始化子工作单元的新实例
        /// </summary>
        /// <param name="parent">父工作单元</param>
        /// <exception cref="ArgumentNullException">当 parent 参数为 null 时抛出</exception>
        public ChildUnitOfWork(IUnitOfWork parent)
        {
            Check.NotNull(parent, nameof(parent));

            _parent = parent;

            _parent.Failed += (sender, args) => { Failed?.Invoke(sender!, args); };
            _parent.Disposed += (sender, args) => { Disposed?.Invoke(sender!, args); };
        }

        public Guid Id => _parent.Id;

        public UnitOfWorkOption Options => _parent.Options;

        public IUnitOfWork? Outer => _parent.Outer;

        public bool IsRoot => _parent.IsRoot;

        public bool IsCompleted => _parent.IsCompleted;

        public bool IsDisposed => _parent.IsDisposed;

        public IServiceProvider ServiceProvider => _parent.ServiceProvider;

        public event EventHandler<UnitOfWorkFailedEventArgs> Failed = default!;

        public event EventHandler<UnitOfWorkEventArgs> Disposed = default!;

        public void AddCompletedHandler(Func<Task> handler)
        {
            _parent.AddCompletedHandler(handler);
        }

        public void Initialize(UnitOfWorkOption options)
        {
            _parent.Initialize(options);
        }

        public Task RollbackAsync(CancellationToken cancellationToken = default)
        {
            return _parent.RollbackAsync(cancellationToken);
        }

        public Task<bool> SaveEntitiesAsync(CancellationToken cancellationToken = default)
        {
            return _parent.SaveEntitiesAsync(cancellationToken);
        }

        public void SetOuter(IUnitOfWork? outer)
        {
            _parent.SetOuter(outer);
        }

        public IDatabaseApi? FindDatabaseApi(string key)
        {
            return _parent.FindDatabaseApi(key);
        }

        public void AddDatabaseApi(string key, IDatabaseApi api)
        {
            _parent.AddDatabaseApi(key, api);
        }

        public IDatabaseApi GetOrAddDatabaseApi(string key, Func<IDatabaseApi> factory)
        {
            return _parent.GetOrAddDatabaseApi(key, factory);
        }

        public int CountTransactionApi()
        {
            return _parent.CountTransactionApi();
        }

        public bool AnyTransactionApi(string key)
        {
            return _parent.AnyTransactionApi(key);
        }

        public ITransactionApi? FindTransactionApi(string key)
        {
            return _parent.FindTransactionApi(key);
        }

        public void AddTransactionApi(string key, ITransactionApi api)
        {
            _parent.AddTransactionApi(key, api);
        }

        public ITransactionApi GetOrAddTransactionApi(string key, Func<ITransactionApi> factory)
        {
            return _parent.GetOrAddTransactionApi(key, factory);
        }

        public Task CommitAsync(CancellationToken cancellationToken = default)
        {
            return Task.CompletedTask;
        }

        public void Dispose()
        {
        }
    }
}